package com.atguigu.gmall.payment.controller;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.atguigu.gmall.common.exception.OrderException;
import com.atguigu.gmall.oms.entity.OrderEntity;
import com.atguigu.gmall.payment.config.AlipayTemplate;
import com.atguigu.gmall.payment.interceptor.LoginInterceptor;
import com.atguigu.gmall.payment.pojo.PayAsyncVo;
import com.atguigu.gmall.payment.pojo.PayVo;
import com.atguigu.gmall.payment.pojo.PaymentInfoEntity;
import com.atguigu.gmall.payment.pojo.UserInfo;
import com.atguigu.gmall.payment.service.PaymentService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;
import java.util.Date;

@Controller
public class PaymentController {

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private AlipayTemplate alipayTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @GetMapping("pay.html")
    public String pay(@RequestParam("orderToken")String orderToken, Model model){

        // 根据订单编号查询订单
        OrderEntity orderEntity = this.paymentService.queryOrderByToken(orderToken);

        // 1.判断订单是否为空
        if (orderEntity == null) {
            throw new OrderException("非法参数！");
        }

        // 2.判断该订单是否属于当前用户
        Long userId = orderEntity.getUserId();
        UserInfo userInfo = LoginInterceptor.getUserInfo();
        Long loginUserId = userInfo.getUserId(); // 登录用户的id
        if (userId != loginUserId){
            throw new OrderException("该订单不属于您！");
        }

        // 3.判断订单支付状态是否为待支付状态
        if (orderEntity.getStatus() != 0) {
            throw new OrderException("当前订单不可支付！");
        }

        model.addAttribute("orderEntity", orderEntity);
        return "pay";
    }

    @GetMapping("alipay.html")
    @ResponseBody // 告诉浏览器端以其他形式展示方法的返回结果集，通常用来响应json
    public String alipay(@RequestParam("orderToken")String orderToken){

        // 根据订单编号查询订单
        OrderEntity orderEntity = this.paymentService.queryOrderByToken(orderToken);

        // 1.判断订单是否为空
        if (orderEntity == null) {
            throw new OrderException("非法参数！");
        }

        // 2.判断该订单是否属于当前用户
        Long userId = orderEntity.getUserId();
        UserInfo userInfo = LoginInterceptor.getUserInfo();
        Long loginUserId = userInfo.getUserId(); // 登录用户的id
        if (userId != loginUserId){
            throw new OrderException("该订单不属于您！");
        }

        // 3.判断订单支付状态是否为待支付状态
        if (orderEntity.getStatus() != 0) {
            throw new OrderException("当前订单不可支付！");
        }

        try {
            // 调用远程接口，打开支付页面
            PayVo payVo = new PayVo();
            payVo.setOut_trade_no(orderToken);
            // 注意 注意 注意！一定要写0.01
            payVo.setTotal_amount("0.01");
            payVo.setSubject("谷粒商城支付平台");

            // 生成对账记录
            Long payId = this.paymentService.savePaymentInfo(payVo);
            payVo.setPassback_params(payId.toString());

            String form = this.alipayTemplate.pay(payVo);

            return form;
        } catch (AlipayApiException e) {
            throw new OrderException("远程接口调用失败，请重试！");
        }
    }

    @GetMapping("pay/success")
    public String paySuccess(){

        return "paysuccess";
    }

    @PostMapping("pay/ok")
    @ResponseBody
    public String payOk(PayAsyncVo asyncVo){

        // 1.验签：确认是支付宝发送的
        Boolean flag = this.alipayTemplate.checkSignature(asyncVo);
        if (!flag){
            return "failure";
        }

        // 2.校验业务参数：app_id、out_trade_no、total_amount
        String appId = asyncVo.getApp_id();
        String currentAppId = alipayTemplate.getApp_id();
        String outTradeNo = asyncVo.getOut_trade_no();
        String totalAmount = asyncVo.getTotal_amount();
        // 获取公共回传参数：对账id
        String payId = asyncVo.getPassback_params();
        PaymentInfoEntity paymentInfoEntity = this.paymentService.queryPaymentInfoById(payId);
        String currentOutTradeNo = paymentInfoEntity.getOutTradeNo();
        BigDecimal currentTotalAmount = paymentInfoEntity.getTotalAmount();
        if (!StringUtils.equals(appId, currentAppId) || !StringUtils.equals(outTradeNo, currentOutTradeNo)
                || currentTotalAmount.compareTo(new BigDecimal(totalAmount)) != 0){
            return "failure";
        }

        // 3.判断支付状态：TRADE_SUCCESS
        String tradeStatus = asyncVo.getTrade_status();
        if (!"TRADE_SUCCESS".equals(tradeStatus)){
            return "failure";
        }

        // 4.先更新对账记录的支付状态，再发送消息给oms，修改订单状态
        paymentInfoEntity.setPaymentStatus(1);
        paymentInfoEntity.setTradeNo(asyncVo.getTrade_no());
        paymentInfoEntity.setCallbackTime(new Date());
        paymentInfoEntity.setCallbackContent(JSON.toJSONString(asyncVo));
        if (this.paymentService.updatePaymentInfo(paymentInfoEntity) == 1) {
            this.rabbitTemplate.convertAndSend("order.exchange", "order.pay", outTradeNo);
        }

        // 5.返回success
        return "success";
    }

}
